import string

from general_utilities import *
from builder import *

class Floorplan:
  def __init__(self,long_string,n_stairs_up,n_stairs_down,difficulty=1,ambient_messages=[],inherited_properties={},exits_to_add=0,entrance_to_add=0,keys_required_somewhere=[]):
    # note on 'keys_required_somewhere' - could be anywhere, no guarantees that they are accessible without first opening every door on the level
    self.long_string = long_string
    self.n_stairs_up = n_stairs_up
    self.n_stairs_down = n_stairs_down
    self.difficulty = difficulty
    self.ambient_messages = ambient_messages
    self.inherited_properties = inherited_properties
    self.exits_to_add = exits_to_add
    self.entrance_to_add = entrance_to_add
    self.keys_required_somewhere = keys_required_somewhere

  def __repr__(self):
    return "-----------------------------\nFloorplan:\n"+self.long_string+"\n\nand "+str(self.n_stairs_up)+" stairs up, "+str(self.n_stairs_down)+" stairs down, "+str(self.exits_to_add)+" exits, "+str(self.entrance_to_add)+" entrances\n-----------------------------\n"
    
class Dungeon_info:
  def __init__(self,long_name,floorplans,translation_table={},description="",entry_message="",exit_message="",all_levels_inherited_properties={},ambient_messages=[],can_be_revisited=0,indicative_difficulty=2):
    self.long_name = long_name
    self.floorplans = floorplans # [[Floorplan]] - possible layouts
    self.translation_table = translation_table # {lowercase or uppercase letter: RM_ code} applied to floorplans
    self.can_be_revisited = can_be_revisited # switch
    self.ambient_messages = ambient_messages # [Possible_message]
    self.entry_message = entry_message # string
    self.exit_message = exit_message # string
    self.all_levels_inherited_properties = all_levels_inherited_properties # {TP_code:value}
    self.description = description # string 
    self.indicative_difficulty = indicative_difficulty # int, only used to decide when it can be accessed randomly
    self.type = None # will be filled in with a D_ code

class Dungeon_library:
  def __init__(self):
    self.d = {} # key is D_ code, value is Dungeon_info
    self.add_item(D_ENTRY,Dungeon_info("Entryway",[
[
Floorplan("""
###
#c#
#b#
#a#
###
""",n_stairs_up=0,n_stairs_down=0),
  ]
      ],translation_table={'a':RM_ENTRY_1,'b':RM_ENTRY_2,'c':RM_ENTRY_3},
        entry_message="You are now entering the dungeon. Use the mouse to move around and fight. If you want to know what something is, right-click on it. Good luck and may you find the Orb!",
        exit_message="So be it...",
        all_levels_inherited_properties={TP_NO_ENCOUNTER:1},
        ambient_messages=[Possible_message(0.02,"You hear an ominous rustling noise...","",0.5),Possible_message(0.02,"Are you sure you want to be an adventurer! It's not too late to back out...","",0.5),Possible_message(0.01,"There must be some treasure around here somewhere...","",0.5)]
    ))
    self.add_item(D_TUTORIAL,Dungeon_info("Tutorial",[
[
Floorplan("""
#####
#abc#
##ed#
#####
""",n_stairs_up=0,n_stairs_down=0),
]
      ],translation_table={'a':RM_TUTORIAL_1,'b':RM_TUTORIAL_2,'c':RM_TUTORIAL_3,'d':RM_TUTORIAL_4,'e':RM_TUTORIAL_5},
        entry_message="Welcome to the tutorial...",
        exit_message="Right! Let the game begin...",
        all_levels_inherited_properties={TP_NO_ENCOUNTER:1},
        ambient_messages=[]
      ))
    self.add_item(D_CROSSROADS,Dungeon_info("The Crossroads",[
[
Floorplan("""
###
#a#
###
""",n_stairs_up=0,n_stairs_down=0),
]
      ],translation_table={'a':RM_CROSSROADS},
        indicative_difficulty=4,
        entry_message="A choice lies before you...",
        exit_message="So be it!",
        description="This is the way to the Crossroads, where you will be able to decide your next steps.",
        all_levels_inherited_properties={TP_NO_ENCOUNTER:1,TP_WALL_TYPE:W_WHITE},
        ambient_messages=[Possible_message(0.05,"It seems quite peaceful here.","",0.5)]
      ))
    self.add_item(D_TREASURE_ROOM,Dungeon_info("Treasure Room",[
[
Floorplan("""
###
#a#
###
""",n_stairs_up=0,n_stairs_down=0),
]
      ],translation_table={'a':RM_TREASURE},
        indicative_difficulty=3,
        entry_message="You have found a treasure room!",
        exit_message="",
        can_be_revisited=1,
        description="This is the door to a treasure room!",
        all_levels_inherited_properties={TP_NO_ENCOUNTER:1,TP_WALL_TYPE:W_WHITE},
        ambient_messages=[Possible_message(0.05,"It seems quite peaceful here.","",0.5)]
      ))
    self.add_item(D_TREASURE_ROOM_2,Dungeon_info("Super Treasure Room",[
[
Floorplan("""
###
#a#
###
""",n_stairs_up=0,n_stairs_down=0),
]
      ],translation_table={'a':RM_TREASURE_2},
        indicative_difficulty=5,
        entry_message="You have found a super treasure room!",
        exit_message="",
        can_be_revisited=1,
        description="This is the door to a super treasure room!",
        all_levels_inherited_properties={TP_NO_ENCOUNTER:1,TP_WALL_TYPE:W_WHITE},
        ambient_messages=[Possible_message(0.05,"It seems quite peaceful here.","",0.5)]
      ))
    self.add_item(D_HALL_OF_HEROES,Dungeon_info("The Hall of Heroes",[
[
Floorplan("""
###
#b#
#a#
###
""",n_stairs_up=0,n_stairs_down=0),
]
      ],translation_table={'a':RM_HEROES_1,'b':RM_HEROES_2},
        indicative_difficulty=3,
        entry_message="Welcome, young adventurer! In this hall you will find no danger, only the quiet graves of those who have come before you.",
        exit_message="Strive to be worthy!",
        description="The Hall of Heroes is the final resting place of many adventurers. You will be able to acquire new garb here.",
        all_levels_inherited_properties={TP_NO_ENCOUNTER:1,TP_FLOOR_TYPE:F_OTHER_COBBLES},
        ambient_messages=[Possible_message(0.05,"It seems quite peaceful here.","",0.5)]
      ))
    self.add_item(D_HALL_OF_CHAMPIONS,Dungeon_info("The Hall of Champions",[
[
Floorplan("""
###
#b#
#a#
###
""",n_stairs_up=0,n_stairs_down=0),
]
      ],translation_table={'a':RM_CHAMPIONS_1,'b':RM_CHAMPIONS_2},
        indicative_difficulty=5,
        entry_message="Welcome, Hero! You have come far to reach this point.",
        exit_message="You venture forth, finely equipped with the best of garb. Soon it will be time for you to confront the Firedrake!",
        description="You will be able to acquire fine garb in the legendary Hall of Champions.",
        all_levels_inherited_properties={TP_NO_ENCOUNTER:1,TP_FLOOR_TYPE:F_OTHER_COBBLES},
        ambient_messages=[Possible_message(0.05,"The deeds of many champions of olden times are celebrated here.","",0.5)]
      ))
    self.add_item(D_FIREDRAKE,Dungeon_info("The Firedrake's Lair",[
[
Floorplan("""
####
#bc#
####
""",n_stairs_up=0,n_stairs_down=0),
Floorplan("""
###
#a#
###
""",n_stairs_up=0,n_stairs_down=0),
]
      ],translation_table={'a':RM_FIREDRAKE_1,'b':RM_FIREDRAKE_2,'c':RM_FIREDRAKE_3},
        indicative_difficulty=6,
        entry_message="Let the final fight begin. May you conclude it as a triumphant hero (and not a small carbonized cinder).",
        description="Behind this door is the long and winding stair leading up to the Firedrake's crag. You have come far to reach this point, are you ready for the final battle?",
        all_levels_inherited_properties={TP_NO_ENCOUNTER:1,TP_FLOOR_TYPE:F_WITH_MAGMA},
        ambient_messages=[Possible_message(0.03,"You smell the reek of sulphur!","",0.5),Possible_message(0.03,"The earth shakes and rumbles...","",0.5),Possible_message(0.03,"You sense that the Orb is near!","",0.5)]
      ))
    self.add_item(D_DROW,Dungeon_info("The Drow's Cavern",[
[
Floorplan("""
###
#a#
###
""",n_stairs_up=0,n_stairs_down=0),
Floorplan("""
####
#bc#
####
""",n_stairs_up=0,n_stairs_down=0),
]
      ],translation_table={'a':RM_DROW_1,'b':RM_DROW_2,'c':RM_DROW_3},
        indicative_difficulty=4,
        entry_message="A powerful enemy awaits. You must defeat him before you can encounter the Firedrake.",
        exit_message="Your next challenge will be to reach the Firedrake's lair!",
        description="A powerful enemy awaits. You must defeat him before you can encounter the Firedrake.",
        all_levels_inherited_properties={TP_NO_ENCOUNTER:1,TP_WALL_TYPE:W_BIGSTONE_DARK},
        ambient_messages=[Possible_message(0.03,"You hear sinister laughter.","",0.5)]
      ))
    self.add_item(D_MAZE,Dungeon_info("The Maze",[
[
Floorplan("""
########
#..S...#
#......#
#......#
#......#
########
""",n_stairs_up=0,n_stairs_down=3,difficulty=3),
Floorplan("""
#########
#.......#
#.......#
#.......#
#########
""",n_stairs_up=3,n_stairs_down=2,difficulty=4),
Floorplan("""
#######
#.....#
#.....#
#.....#
#.....#
#...E.#
#######
""",n_stairs_up=2,n_stairs_down=0,difficulty=4),
]
      ],indicative_difficulty=4,
        entry_message="You have entered a labyrinth.",
        exit_message="Finally!",
        description="This door leads to a large and winding Maze of passages.",
        all_levels_inherited_properties={TP_ORGANIC_PROB:0,TP_OPEN_PROB:0,TP_NON_MAZY_PROB:0.1,TP_MAZY_PROB:2,TP_CORRIDOR_PROB:2,
                                         TP_RANDOM_MONSTER_CHANCE:0.4,
                                         TP_LOOT_CHANCE:0.3,
                                         TP_THEME_PROBS:{E_OTHER:1,E_ORC:0},
                                         TP_TERRAIN_VETO_PROBS:{'!':0.6,'*':0.2,')':0,'(':0,'?':0,'^':0,'3':0.5,'8':0.2,'@':0,'7':1,'9':1,':':0,'&':0}},
        ambient_messages=[Possible_message(0.03,"There must be some way out of here...","",0.5)]
      ))
    self.add_item(D_CAVE,Dungeon_info("The Cave",[
[
Floorplan("""
###########
###.....###
##..#....##
#S.......##
##....#..E#
###......##
###########
""",n_stairs_up=0,n_stairs_down=0,difficulty=3),
]
      ],indicative_difficulty=3,
        entry_message="It seems very tranquil in this quiet grotto beneath the earth. Somewhere water is dripping.",
        exit_message="",
        description="There is a cave entrance here. Why don't you go inside? It will be quite safe, unless you fall down a hole, hit your head on a stalactite or get eaten.",
        all_levels_inherited_properties={TP_FLOOR_TYPE:F_FLECKS,
                                         TP_ORGANIC_PROB:3,TP_NON_ORGANIC_PROB:0,
                                         TP_RANDOM_MONSTER_CHANCE:0.8,
                                         TP_LOOT_CHANCE:0.4,
                                         TP_THEME_PROBS:{E_CREEPY_CRAWLY:2,E_ORC:0,E_WIZARD:0,E_UNDEFENDED_TREASURE:0},
                                         TP_TERRAIN_VETO_PROBS:{'!':0.4,'*':1,')':1,'(':1,'?':1,'^':0,'3':1,'8':1,'@':0.7,'7':1,'9':1,':':1,'&':1}},
        ambient_messages=[Possible_message(0.03,"You hear water dripping.","create_water",0.5),Possible_message(0.03,"Something small drops from the ceiling and scuttles down the back of your neck.","",0.5)]
      ))
    self.add_item(D_EASY_DUNGEON,Dungeon_info("The Easy Dungeon",[
[
Floorplan("""
#######
##...##
#S...d#
##...##
#######
""",n_stairs_up=0,n_stairs_down=0,difficulty=1,inherited_properties={TP_LOOT_CHANCE:0.4}),Floorplan("""
#######
##...##
#e...<#
##...##
#######
""",n_stairs_up=0,n_stairs_down=0,difficulty=2,inherited_properties={TP_RANDOM_MONSTER_CHANCE:0.4}),Floorplan("""
#######
##...##
#<...E#
##...##
#######
""",n_stairs_up=0,n_stairs_down=0,difficulty=2)
]
      ],translation_table = {'d':RM_STAIRSDOWN_RIGHT_WITH_RANDOMDOOR_LEFT,'e':RM_STAIRSDOWN_LEFT_WITH_RANDOMDOOR_RIGHT},
        entry_message="This area is suitable for adventurers under the age of 12 with parental supervision. Warning - may contain monsters.",
        exit_message="Right, back to the main dungeon. You will find yourself in a relatively safe area, though.",
        description="An extra-easy dungeon for nervous adventurers.",
        all_levels_inherited_properties={TP_FIERY_PROB:0.2,TP_CLASSIC_PROB:1.5,TP_NON_CLASSIC_PROB:0.5,TP_ORGANIC_PROB:0.2,TP_MAZY_PROB:0.5,
                                         TP_RANDOM_MONSTER_CHANCE:0.6,
                                         TP_LOOT_CHANCE:0.6,
                                         TP_ALLOWED_ITEMS:[O_SWORD,O_SHOES,O_COPPER,O_SILVER,O_WAND,O_BOW,O_SMALL_FOOD,O_HEALING_POT,O_MAGIC_POT,O_POISONED_DAGGER,O_BOOTS,O_STAFF,O_STONESKIN_POT],
                                         TP_ALLOWED_SLOTS:[],
                                         TP_TERRAIN_VETO_PROBS:{'!':0,'*':0,')':1,'(':0.5,'?':0,'^':0,'3':1,'8':0,'@':0,'7':1,'9':1,':':0,'&':0}},
        ambient_messages=[Possible_message(0.01,"If you want to know what something on the screen is, try clicking the right mouse button on it.","",0.5),Possible_message(0.01,"Try the Tutorial if you're not sure what to do.","",0.5),Possible_message(0.013,"If you forget how to use your powers, click the Powers button for a reminder.","",0.5),Possible_message(0.013,"If you feel lost, try clicking the Map button.","",0.5)]
      ))
    self.add_item(D_QUIET_DUNGEON,Dungeon_info("The Quiet Dungeon",[
[
Floorplan("""
######
#....#
#....#
#..S.#
######
""",n_stairs_up=0,n_stairs_down=3,difficulty=3),
Floorplan("""
######
#....#
#....#
#....#
######
""",n_stairs_up=3,n_stairs_down=3,difficulty=4),
Floorplan("""
######
#.E..#
#....#
#....#
######
""",n_stairs_up=3,n_stairs_down=0,difficulty=4),
]
      ],indicative_difficulty=3,
        entry_message="It seems very quiet in here. The floor is covered in thick dust, suggesting that no one has passed this way for a long, long time. The way forward is draped with hanging cobwebs.",
        exit_message="",
        description="This door leads to one of the quieter parts of the dungeon.",
        all_levels_inherited_properties={TP_ORGANIC_PROB:0,TP_MAZY_PROB:0.3,TP_FIERY_PROB:0,TP_WET_PROB:0,
                                         TP_RANDOM_MONSTER_CHANCE:0.3,
                                         TP_LOOT_CHANCE:0.2,
                                         TP_ALLOWED_ITEMS:[],
                                         TP_ALLOWED_SLOTS:[SL_AMULET,SL_BOOTS,SL_FOOD,SL_GLOVES,SL_RING,SL_POTION],
                                         TP_THEME_PROBS:{E_OTHER:0.5,E_CREEPY_CRAWLY:2,E_DISGUISED:3,E_UNDEAD:2,E_WIZARD:1},
                                         TP_TERRAIN_VETO_PROBS:{'!':1,'*':1,'3':0.5,'8':0,'@':0,'7':0.5,'9':0.5,':':0,'&':0}}
      ))
    self.add_item(D_FIERY_PITS,Dungeon_info("The Fiery Pits",[
[
Floorplan("""
#######
##...##
#S...a#
##...##
#######
""",n_stairs_up=0,n_stairs_down=0,difficulty=5),
Floorplan("""
#######
##...##
#b...<#
##...##
#######
""",n_stairs_up=0,n_stairs_down=0,difficulty=5),
Floorplan("""
#######
##...##
#<...E#
##...##
#######
""",n_stairs_up=0,n_stairs_down=0,difficulty=6),
]
      ],translation_table = {'a':RM_STAIRSDOWN_RIGHT_WITH_RANDOMDOOR_LEFT,'b':RM_STAIRSDOWN_LEFT_WITH_RANDOMDOOR_RIGHT},
        indicative_difficulty=5,
        entry_message="It is as hot as an oven down here! The walls seem to radiate heat... and are the soles of your boots scorching?",
        exit_message="Phew! Fresh air...",
        description="The glow of flames can be seen through this doorway...",
        ambient_messages=[Possible_message(0.02,"You smell the reek of sulphur!","",0.5),Possible_message(0.02,"After this the Firedrake's breath will feel like a cooling breeze!","",0.5),Possible_message(0.02,"The heat is scorching...","",0.5)],
        all_levels_inherited_properties={TP_ORGANIC_PROB:0,TP_MAZY_PROB:0.3,TP_FIERY_PROB:3,TP_NON_FIERY_PROB:0.4,TP_WET_PROB:0,
                                         TP_FLOOR_TYPE:F_WITH_MAGMA,
                                         TP_LOOT_CHANCE:0.6,
                                         TP_ALLOWED_ITEMS:[],
                                         TP_ALLOWED_SLOTS:[SL_AMULET,SL_MONEY,SL_MELEE,SL_MISSILE,SL_GLOVES,SL_RING,SL_MISC_ITEM],
                                         TP_THEME_PROBS:{E_CREEPY_CRAWLY:2,E_GOBLIN:0,E_ORC:2,E_UNDEAD:0,E_WIZARD:0.5},
                                         TP_TERRAIN_VETO_PROBS:{'!':1,'*':0,'3':1,'8':1,'@':1,'7':1,'9':1,':':1,'&':1}}
      ))
    self.add_item(D_CRYPT,Dungeon_info("The Crypt",[
[
Floorplan("""
######
#....#
#S...#
#....#
######
""",n_stairs_up=0,n_stairs_down=2,difficulty=3),
Floorplan("""
######
#....#
#....#
#....#
######
""",n_stairs_up=2,n_stairs_down=2,difficulty=4),
Floorplan("""
######
#..E.#
#....#
#....#
######
""",n_stairs_up=2,n_stairs_down=0,difficulty=5),
]
      ],indicative_difficulty=4,
        entry_message="You are entering a mausoleum. Bones and skulls can be seen littered on the ground. There is an ominous dusty smell of decay...",
        exit_message="",
        description="This door leads into a complex of underground tombs and crypts.",
        ambient_messages=[Possible_message(0.02,"You hear a long-drawn-out creak...","",0.5),Possible_message(0.02,"You hear a ghostly call!","",0.5)],
        all_levels_inherited_properties={TP_ORGANIC_PROB:0,TP_MAZY_PROB:0,TP_FIERY_PROB:0.3,TP_WET_PROB:0,TP_NON_CLASSIC_PROB:0.1,TP_OPEN_PROB:0.2,
                                         TP_WALL_TYPE:W_BIGSTONE_DARK,
                                         TP_LOOT_CHANCE:0.6,
                                         TP_ALLOWED_ITEMS:[O_SMALL_FOOD],
                                         TP_ALLOWED_SLOTS:[SL_MONEY,SL_GARB,SL_AMULET,SL_POTION,SL_MELEE,SL_MISC_ITEM],
                                         TP_THEME_PROBS:{E_UNDEAD:2.5,E_WIZARD:1,E_UNDEFENDED_TREASURE:1,E_CREEPY_CRAWLY:1,E_OTHER:0},
                                         TP_TERRAIN_VETO_PROBS:{'!':1,'*':0.8,'3':0.3,'8':0,'@':1,'7':0,'9':0,':':0.3,'&':0}}
      ))
    self.add_item(D_GOBLIN_CAVE,Dungeon_info("The Cave of the Goblin King",[
[
Floorplan("""
############
##.#....####
##.#.#....S#
#........###
##....#...##
###E#....###
############
""",n_stairs_up=0,n_stairs_down=0,difficulty=3),
]
      ],indicative_difficulty=4,
        entry_message="A sign is carved into the lintel of the door. 'Trobnose woz ere' it says. What can this portend?",
        exit_message="You devoutly wish never to hear the sound of 'Daddu-Yaddu' again, for as long as you live!",
        description="This is the home of the Goblin King, and of all other goblins of different shapes and sizes.",
        all_levels_inherited_properties={TP_FLOOR_TYPE:F_FLECKS,
                                         TP_FIERY_PROB:0,TP_WET_PROB:0,TP_ORGANIC_PROB:2,TP_OPEN_PROB:0.3,
                                         TP_RANDOM_MONSTER_CHANCE:1,
                                         TP_LOOT_CHANCE:0.6,
                                         TP_ALLOWED_ITEMS:[],
                                         TP_ALLOWED_SLOTS:[SL_FOOD,SL_MONEY,SL_POTION,SL_MELEE,SL_MISSILE,SL_BOOTS,SL_GLOVES],
                                         TP_THEME_PROBS:{E_GOBLIN:3,E_ORC:0,E_UNDEAD:0,E_OTHER:0.3},
                                         TP_TERRAIN_VETO_PROBS:{'!':0.7,'*':1,')':0,'(':0.6,'?':0,'^':0,'3':1,'8':1,'@':0,'7':1,'9':1,':':0.5,'&':1}},
        ambient_messages=[]
      ))

    
  def add_item(self,type,definition):
    self.d[type] = definition
    self.d[type].type = type
    
dlib = Dungeon_library()

def get_main_dungeon_floorplan(difficulty,n_stairs_down,n_stairs_up,min_exits,max_exits,keys_required_somewhere=[],entrance=0):
  # note on 'keys_required_somewhere' - could be anywhere, no guarantees that they are accessible without first opening every door on the level
  while 1:
    n_fixed_stairs_down = 0
    n_fixed_stairs_up = 0
    n_fixed_exits = 0
    fixed_entrance = 0
    ambient_messages = []
    inherited_properties = {}
    can_have_random_properties = 0
    can_change_stairs_to_exits_and_entrances = 0
    i = random.randint(1,40)
    print "i is ",i
    if i<=16:
      # simple rectangular level
      can_have_random_properties = 1
      while 1:
        r_width =random.randint(2,5)
        r_height =random.randint(2,5)
        if r_width*r_height>=6 and r_width*r_height<=20:
          break
      plan = "\n"
      for j in range(0,r_width+2):
        plan = plan + "#"
      plan = plan + "\n"
      for k in range(0,r_height):
        plan = plan + "#"
        for j in range(1,r_width+1):
          plan = plan + "."
        plan = plan + "#\n"      
      for j in range(0,r_width+2):
        plan = plan + "#"
      plan = plan + "\n"
    elif i<=21:
      # simple rectangular level with a locked door to the only stairs down, on the left side
      if n_stairs_down<>1:
        continue
      can_have_random_properties = 1
      while 1:
        r_width =random.randint(2,5)
        r_height =random.randint(2,5)
        if r_width*r_height>=6 and r_width*r_height<=20:
          break
      row_with_door = random.randint(0,r_height-1)
      plan = "\n"
      for j in range(0,r_width+3):
        plan = plan + "#"
      plan = plan + "\n"
      for k in range(0,r_height):
        if k==row_with_door:
          plan = plan + '#b'
          for j in range(2,r_width+2):
            plan = plan + "."
          plan = plan + "#\n"      
        else:
          plan = plan + '##'
          for j in range(2,r_width+2):
            plan = plan + "."
          plan = plan + "#\n"      
      for j in range(0,r_width+3):
        plan = plan + "#"
      plan = plan + "\n"  
      n_fixed_stairs_down = 1
    elif i<=26:
      # simple rectangular level with a locked door to the only stairs down, on the right side
      if n_stairs_down<>1:
        continue
      can_have_random_properties = 1
      while 1:
        r_width =random.randint(2,5)
        r_height =random.randint(2,5)
        if r_width*r_height>=6 and r_width*r_height<=20:
          break
      row_with_door = random.randint(0,r_height-1)
      plan = "\n"
      for j in range(0,r_width+3):
        plan = plan + "#"
      plan = plan + "\n"
      for k in range(0,r_height):
        if k==row_with_door:
          plan = plan + '#'
          for j in range(1,r_width+1):
            plan = plan + "."
          plan = plan + "a#\n"      
        else:
          plan = plan + '#'
          for j in range(1,r_width+1):
            plan = plan + "."
          plan = plan + "##\n"      
      for j in range(0,r_width+3):
        plan = plan + "#"
      plan = plan + "\n"  
      n_fixed_stairs_down = 1
    elif i<=27:
      can_have_random_properties = 1
      can_change_stairs_to_exits_and_entrances = 1
      plan = """
#########
##.#.#.##
#<.....>#
##.#.#.##
#########
"""
      n_fixed_stairs_down = 1
      n_fixed_stairs_up = 1
    elif i<=28:
      can_have_random_properties = 1
      can_change_stairs_to_exits_and_entrances = 1
      plan = """
#####
#.>.#
#.#.#
#...#
#.#.#
#.<.#
#####
"""
      n_fixed_stairs_down = 1
      n_fixed_stairs_up = 1
    elif i<=29:
      can_have_random_properties = 1
      can_change_stairs_to_exits_and_entrances = 1
      plan = """
#######
#.....#
#>###<#
#.....#
#######
"""
      n_fixed_stairs_down = 1
      n_fixed_stairs_up = 1
    elif i<=30:
      if n_stairs_down>0:
        continue
      plan = """
#######
#F.<.G#
#######
"""
      n_fixed_stairs_up = 1
      n_fixed_exits = 4
    elif i<=31:
      plan = """
#############
#>....<....>#
######.######
######.######
######.######
######.######
######>######
#############
"""
      n_fixed_stairs_up = 1
      n_fixed_stairs_down = 3
      can_change_stairs_to_exits_and_entrances = 1
    elif i<=32:
      plan = """
###########
#...###...#
#....H....#
#...#.#...#
#####.#####
####...####
####...####
####...####
###########
"""
      n_fixed_stairs_up = 1
    elif i<=33:
      can_have_random_properties = 1
      plan = """
#######
#..#..#
#..#..#
#..m..#
#..#..#
#..#..#
#######
"""
    elif i<=34:
      can_have_random_properties = 1
      plan = """
#######
#..#..#
#..m..#
#..#..#
#..#..#
#..m..#
#..#..#
#######
"""
    elif i<=35:
      can_have_random_properties = 1
      can_change_stairs_to_exits_and_entrances = 1
      plan = """
########
#...>..#
#..###.#
#<.#on.#
#..###.#
#...>..#
########
"""
      n_fixed_stairs_down = 2
      n_fixed_stairs_up = 1
    elif i<=38:
      while 1:
        r_width =random.randint(2,4)*2+1
        r_height =random.randint(2,4)*2+1
        if r_width*r_height>=35 and r_width*r_height<=60:
          break
      temp_grid = Grid(r_width,r_height)
      temp_grid.fill_with_maze(0,0,0.5)
      plan = "\n"
      for j in range(r_width+2):
          plan = plan + '#'
      plan = plan + '\n'
      for k in range(r_height):
        plan = plan + '#'
        for j in range(r_width):
          plan = plan + temp_grid.g[k][j]
        plan = plan + '#\n'
      for j in range(r_width+2):
          plan = plan + '#'
      plan = plan + '\n'
      if random.random()<0.4:
        inherited_properties[TP_MAZY_PROB] = 3
        inherited_properties[TP_NON_MAZY_PROB] = 0.1
        inherited_properties[TP_CORRIDOR_PROB] = 2
      elif random.random()<0.5:
        inherited_properties[TP_ORGANIC_PROB] = 3
        inherited_properties[TP_NON_ORGANIC_PROB] = 0
    elif i<=40:
      can_have_random_properties = 1
      while 1:
        r_width =random.randint(5,8)
        r_height =random.randint(5,8)
        if r_width*r_height>=30 and r_width*r_height<=60:
          break      
      temp_grid = Grid(r_width,r_height,fill_with='#')
      start_x = random.randint(2,4)
      start_y = random.randint(2,4)
      point = Grid_point(start_y,start_x)
      temp_grid.set_cell(point,'.')
      rooms_opened = 1
      rooms_to_open =random.randint(15,25)
      while rooms_opened <= rooms_to_open:
        random_x = random.randint(0,r_width-1)
        random_y = random.randint(0,r_height-1)
        point = Grid_point(random_y,random_x)
        next_to_open = 0
        if random_x>0:
          if temp_grid.get_cell(Grid_point(random_y,random_x-1))=='.':
            next_to_open = 1
        if random_y>0:
          if temp_grid.get_cell(Grid_point(random_y-1,random_x))=='.':
            next_to_open = 1   
        if random_x<r_width-1:
          if temp_grid.get_cell(Grid_point(random_y,random_x+1))=='.':
            next_to_open = 1
        if random_y<r_height-1:
          if temp_grid.get_cell(Grid_point(random_y+1,random_x))=='.':
            next_to_open = 1                     
        if not next_to_open:
          continue
        temp_grid.set_cell(point,'.')
        rooms_opened = rooms_opened + 1
      plan = "\n"
      for j in range(r_width+2):
          plan = plan + '#'
      plan = plan + '\n'
      for k in range(r_height):
        plan = plan + '#'
        for j in range(r_width):
          plan = plan + temp_grid.g[k][j]
        plan = plan + '#\n'
      for j in range(r_width+2):
          plan = plan + '#'
      plan = plan + '\n'
    else:
      continue
    # done with i loop
    if can_change_stairs_to_exits_and_entrances:
      if n_stairs_down==0 and n_fixed_stairs_down>0:
        less_than_count = string.count(plan,'>')
        plan = string.replace(plan,'>','E')
        n_fixed_exits = n_fixed_exits + less_than_count
        n_fixed_stairs_down = n_fixed_stairs_down - less_than_count
      if n_stairs_down==0 and n_fixed_stairs_up==1 and fixed_entrance==0:
        greater_than_count = string.count(plan,'<')
        plan = string.replace(plan,'<','S')
        fixed_entrance = greater_than_count
        n_fixed_stairs_up = n_fixed_stairs_up - greater_than_count
    if n_fixed_stairs_down <= n_stairs_down:
      n_random_stairs_down = n_stairs_down - n_fixed_stairs_down
    else:
      continue
    if n_fixed_stairs_up <= n_stairs_up:
      n_random_stairs_up = n_stairs_up - n_fixed_stairs_up
    else:
      continue
    n_exits = random.randint(min_exits,max_exits)
    if n_fixed_exits <= n_exits:
      n_random_exits = n_exits - n_fixed_exits
    else:
      continue
    if entrance and not fixed_entrance:
      random_entrance=1
    elif fixed_entrance and not entrance:
      continue
    else:
      random_entrance = 0
    if can_have_random_properties:
      # TO DO
      #ambient_messages.append(?)
      #inherited_properties[?] = ?
      pass
    return Floorplan(plan,n_stairs_up=n_random_stairs_up,n_stairs_down=n_random_stairs_down,exits_to_add=n_random_exits,entrance_to_add=random_entrance,difficulty=difficulty,ambient_messages=ambient_messages,inherited_properties=inherited_properties,keys_required_somewhere=keys_required_somewhere)
  
def get_main_dungeon_info(dungeon_level):
  translation_table = {'a':RM_STAIRSDOWN_RIGHT_WITH_RANDOMDOOR_LEFT,
                       'b':RM_STAIRSDOWN_LEFT_WITH_RANDOMDOOR_RIGHT,
                       'c':RM_STAIRSDOWN_UP_WITH_RANDOMDOOR_DOWN,
                       'd':RM_STAIRSDOWN_DOWN_WITH_RANDOMDOOR_UP,
                       'e':RM_STAIRSUP_RIGHT_WITH_RANDOMDOOR_LEFT,
                       'f':RM_STAIRSUP_LEFT_WITH_RANDOMDOOR_RIGHT,
                       'g':RM_STAIRSUP_UP_WITH_RANDOMDOOR_DOWN,
                       'h':RM_STAIRSUP_DOWN_WITH_RANDOMDOOR_UP,
                       'i':RM_STAIRSDOWN_RIGHT_WITH_GOLDDOOR_LEFT,
                       'j':RM_STAIRSDOWN_LEFT_WITH_GOLDDOOR_RIGHT,
                       'k':RM_STAIRSUP_RIGHT_WITH_GOLDDOOR_LEFT,
                       'l':RM_STAIRSUP_LEFT_WITH_GOLDDOOR_RIGHT,
                       'm':RM_NORMALDOOR_LEFT_RANDOMDOOR_RIGHT,
                       'n':RM_NORMALDOOR_RIGHT_RANDOMDOOR_LEFT,
                       'o':RM_GUARANTEED_TREASURE_DOOR_RIGHT,
                       'x':RM_NEED_GOLDKEY_TO_EXIT,
                       'z':RM_RIVER_SW_NE_V1,
                       'A':RM_RIVER_SW_NE_V2,
                       'B':RM_RIVER_SW_N,
                       'C':RM_RIVER_S_NW_NE,
                       'D':RM_RIVER_NW_SE, # no E
                       'F':RM_TWO_EXITS_AND_DOOR_RIGHT,
                       'G':RM_TWO_EXITS_AND_DOOR_LEFT,
                       'H':RM_LOCKED_DOORS_W_E_S_STAIRSUP_N,
                       } # and: #, . (random room), < or > (random room with guaranteed stairs), 
                         #      S (start with entrance), E (exit)
  floorplan_type = random.randint(1,20)
  if floorplan_type<=3:
    exits_1_2 =random.randint(1,2)
    floorplans = [
      get_main_dungeon_floorplan(difficulty=dungeon_level  ,n_stairs_down=exits_1_2,n_stairs_up=0,min_exits=0,max_exits=1,entrance=1),
      get_main_dungeon_floorplan(difficulty=dungeon_level+1,n_stairs_up=exits_1_2,n_stairs_down=0,min_exits=1,max_exits=3)
    ]
  elif floorplan_type<=6:
    exits_1_2 =random.randint(2,3)
    exits_2_3 =random.randint(2,3)
    floorplans = [
      get_main_dungeon_floorplan(difficulty=dungeon_level  ,n_stairs_down=exits_1_2,n_stairs_up=0,min_exits=0,max_exits=0,entrance=1),
      get_main_dungeon_floorplan(difficulty=dungeon_level  ,n_stairs_down=exits_2_3,n_stairs_up=exits_1_2,min_exits=0,max_exits=0),
      get_main_dungeon_floorplan(difficulty=dungeon_level+1,n_stairs_down=0,n_stairs_up=exits_2_3,min_exits=2,max_exits=4)
    ]
  elif floorplan_type<=9:
    exits_1_2 =random.randint(1,3)
    exits_2_3 =random.randint(1,3)
    floorplans = [
      get_main_dungeon_floorplan(difficulty=dungeon_level  ,n_stairs_down=exits_1_2,n_stairs_up=0,min_exits=0,max_exits=0,entrance=1),
      get_main_dungeon_floorplan(difficulty=dungeon_level+1,n_stairs_down=exits_2_3,n_stairs_up=exits_1_2,min_exits=1,max_exits=1),
      get_main_dungeon_floorplan(difficulty=dungeon_level+1,n_stairs_down=0,n_stairs_up=exits_2_3,min_exits=2,max_exits=3)
    ]
  elif floorplan_type<=12:
    exits_1_2 =random.randint(1,3)
    exits_2_3 =random.randint(1,3)
    exits_3_4 =random.randint(1,3)
    floorplans = [
      get_main_dungeon_floorplan(difficulty=dungeon_level  ,n_stairs_down=exits_1_2,n_stairs_up=0,min_exits=0,max_exits=0,entrance=1),
      get_main_dungeon_floorplan(difficulty=dungeon_level+1,n_stairs_down=exits_2_3,n_stairs_up=exits_1_2,min_exits=0,max_exits=0),
      get_main_dungeon_floorplan(difficulty=dungeon_level+1,n_stairs_down=exits_3_4,n_stairs_up=exits_2_3,min_exits=2,max_exits=4),
      get_main_dungeon_floorplan(difficulty=dungeon_level+2,n_stairs_down=0,n_stairs_up=exits_3_4,min_exits=1,max_exits=3)
    ]
  elif floorplan_type<=15:
    exits_1_2 = random.randint(1,2)
    floorplans = [
      get_main_dungeon_floorplan(difficulty=dungeon_level,n_stairs_down=exits_1_2,n_stairs_up=0,min_exits=0,max_exits=1,entrance=1),
      get_main_dungeon_floorplan(difficulty=dungeon_level,n_stairs_up=exits_1_2,n_stairs_down=0,min_exits=1,max_exits=3)
    ]
  elif floorplan_type==16:
    exits_1_2 =random.randint(1,3)
    exits_2_3 =random.randint(1,3)
    exits_3_4 =random.randint(1,3)
    floorplans = [
Floorplan("""
#######
#x....#
#.....#
#.....#
#######
""",n_stairs_up=0,n_stairs_down=exits_1_2,exits_to_add=0,difficulty=dungeon_level),
      get_main_dungeon_floorplan(difficulty=dungeon_level  ,n_stairs_down=exits_2_3,n_stairs_up=exits_1_2,min_exits=0,max_exits=0),
      get_main_dungeon_floorplan(difficulty=dungeon_level+1,n_stairs_down=exits_3_4,n_stairs_up=exits_2_3,min_exits=0,max_exits=0),
      get_main_dungeon_floorplan(difficulty=dungeon_level+1,n_stairs_down=0,n_stairs_up=exits_3_4,min_exits=0,max_exits=0,keys_required_somewhere=['$']),
    ]
  elif floorplan_type==17:
    exits_1_2 =random.randint(1,3)
    exits_2_3 =random.randint(1,3)
    exits_3_4 =random.randint(1,3)
    floorplans = [
Floorplan("""
########
#.....##
#S....a#
#.....##
########
""",n_stairs_up=0,n_stairs_down=0,exits_to_add=0,difficulty=dungeon_level),
    Floorplan("""
########
#......#
#......#
#......#
########
""",n_stairs_up=1,n_stairs_down=2,exits_to_add=2,difficulty=dungeon_level),
    Floorplan("""
########
#......#
#.....E#
#......#
########
""",n_stairs_up=2,n_stairs_down=0,exits_to_add=1,difficulty=dungeon_level+1)
    ]
  elif floorplan_type==18:
    floorplans = [
Floorplan("""
########
#.....##
#S....a#
#.....##
########
""",n_stairs_up=0,n_stairs_down=0,exits_to_add=0,difficulty=dungeon_level),
    Floorplan("""
########
#......#
#......#
#......#
########
""",n_stairs_up=1,n_stairs_down=2,exits_to_add=2,difficulty=dungeon_level),
    Floorplan("""
########
#......#
#.....E#
#......#
########
""",n_stairs_up=2,n_stairs_down=0,exits_to_add=1,difficulty=dungeon_level+1)
    ]
  elif floorplan_type==19:
    exits_1_2 =random.randint(1,3)
    exits_2_3 =random.randint(1,3)
    floorplans = [
      get_main_dungeon_floorplan(difficulty=dungeon_level  ,n_stairs_down=exits_1_2,n_stairs_up=0,min_exits=0,max_exits=0,entrance=1),
      get_main_dungeon_floorplan(difficulty=dungeon_level+1,n_stairs_down=exits_2_3,n_stairs_up=exits_1_2,min_exits=1,max_exits=1),
Floorplan("""
######
#D.A.#
#.C..#
#.B..#
#z...#
######
""",n_stairs_up=exits_2_3,n_stairs_down=0,exits_to_add=1,difficulty=dungeon_level+1)
    ]
  elif floorplan_type==20:
    exits_1_2 =random.randint(2,3)
    exits_2_3 = 1
    floorplans = [
      get_main_dungeon_floorplan(difficulty=dungeon_level  ,n_stairs_down=exits_1_2,n_stairs_up=0,min_exits=0,max_exits=0,entrance=1),
      get_main_dungeon_floorplan(difficulty=dungeon_level+1,n_stairs_down=exits_2_3,n_stairs_up=exits_1_2,min_exits=0,max_exits=0),
      get_main_dungeon_floorplan(difficulty=dungeon_level+1,n_stairs_down=0,n_stairs_up=exits_2_3,min_exits=4,max_exits=4)
    ]
  # if you add more here, remember you are responsible for putting an entrance on the top floor
  print floorplans
  print "type",floorplan_type
  terrain_veto_list = {'8':0,'&':0,':':0,'@':0.4,'7':0}
  if dungeon_level<2:
    terrain_veto_list['^'] = 0.5
    terrain_veto_list['*'] = 0.7
    terrain_veto_list['9'] = 1
    terrain_veto_list['?'] = 1
    terrain_veto_list['('] = 1
    terrain_veto_list['3'] = 1
    terrain_veto_list[')'] = 1
    terrain_veto_list['!'] = 0
  if dungeon_level<3:
    terrain_veto_list['^'] = 0
    terrain_veto_list['*'] = 0.5
    terrain_veto_list['9'] = 0.5
    terrain_veto_list['?'] = 0.7
    terrain_veto_list['('] = 1
    terrain_veto_list['3'] = 1
    terrain_veto_list[')'] = 1
    terrain_veto_list['!'] = 0.3
  if dungeon_level<4:
    terrain_veto_list['*'] = 0
    terrain_veto_list['9'] = 0
    terrain_veto_list['?'] = 0.5
    terrain_veto_list['('] = 0.7
    terrain_veto_list['3'] = 1
    terrain_veto_list[')'] = 1
    terrain_veto_list['!'] = 0.5
  if dungeon_level<5:
    terrain_veto_list['?'] = 0
    terrain_veto_list['('] = 0.5
    terrain_veto_list['3'] = 0.7
    terrain_veto_list[')'] = 0.5
    terrain_veto_list['!'] = 0.7    
  if dungeon_level >= 5:
    terrain_veto_list['('] = 0
    terrain_veto_list['3'] = 0
    terrain_veto_list[')'] = 0    
  all_levels_inherited_properties = {TP_NON_CLASSIC_PROB:0.5,TP_FIERY_PROB:0.5,TP_MAZY_PROB:0.5,TP_ORGANIC_PROB:0.5,
                                     TP_RANDOM_MONSTER_CHANCE:0.7,TP_LOOT_CHANCE:0.5,
                                     TP_THEME_PROBS:{E_WIZARD:0.5},
                                     TP_TERRAIN_VETO_PROBS:terrain_veto_list}
  ambient_messages = []
  # e.g.:
#ambient_messages=[Possible_message(0.03,"You smell the reek of sulphur!","",0.5),Possible_message(0.03,"The earth shakes and rumbles...","",0.5),Possible_message(0.03,"You sense that the Orb is near!","",0.5)]
  return Dungeon_info("The Main Dungeon",[floorplans],translation_table=translation_table,description="This leads back into the main dungeon.",all_levels_inherited_properties=all_levels_inherited_properties,ambient_messages=ambient_messages,can_be_revisited=1,indicative_difficulty=dungeon_level)
  